﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
using DukeNUS.FacilitiesPlanning.FPSystem.Data;
using DukeNUS.FacilitiesPlanning.FPSystem.Helpers.Cryptography;
using DukeNUS.FacilitiesPlanning.FPSystem.Models;
using DukeNUS.FacilitiesPlanning.FPSystem.Models.Account;
using System.Diagnostics;

namespace DukeNUS.FacilitiesPlanning.FPSystem.Controllers
{
    public class AccountController : Controller
    {
        //
        // GET: /Account/

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public JsonResult ChangePassword(AccountPasswordDetail passwordDetail)
        {
            var response = new PasswordUpdateResponse()
            {
                AccountPasswordDetail = passwordDetail,
            };

            if (!ModelState.IsValid)
                response.Errors = response.GetErrors(ModelState);
            else
            {
                var currentPassword = Cryptographer.Encrypt(passwordDetail.CurrentPassword);
                var newPassword = Cryptographer.Encrypt(passwordDetail.NewPassword);
                var validatingPassword = Cryptographer.Encrypt(passwordDetail.ValidatingPassword);

                if (!validatingPassword.Equals(newPassword))
                    response.Errors = new ErrorResponse[] {
                        new ErrorResponse() {
                            For = "ValidatingPassword",
                            Message  = ApplicationErrorMessage.GetErrorMessage(ApplicationErrorMessages.PasswordsDoesNotMatch)
                        }
                    };
                else
                {
                    if (Session[ApplicationSessionKeys.CurrentUser] == null)
                        response.Errors = new ErrorResponse[]   {
                            new ErrorResponse() {
                                Message = ApplicationErrorMessage.GetErrorMessage(ApplicationErrorMessages.ActionNotAllowed)
                            }
                        };
                    else
                    {
                        var currentUser = (ApplicationUser)Session[ApplicationSessionKeys.CurrentUser];
                        var allowed = true;

                        if (!currentUser.User.IsAdmin) allowed = (currentUser.User.UserID == passwordDetail.UserID);

                        if (!allowed)
                            response.Errors = new ErrorResponse[]   {
                                new ErrorResponse() {
                                    Message = ApplicationErrorMessage.GetErrorMessage(ApplicationErrorMessages.ActionNotAllowed)
                                }
                            };
                        else
                        {
                            using (TransactionScope trans = new TransactionScope())
                            {
                                using (DukeNUSDatabase db = new DukeNUSDatabase())
                                {
                                    var query = from users in db.Users
                                                where users.UserID == passwordDetail.UserID
                                                select users;

                                    if (!query.Any())
                                        response.Errors = new ErrorResponse[]   {
                                            new ErrorResponse() {
                                                Message = ApplicationErrorMessage.GetErrorMessage(ApplicationErrorMessages.ActionNotAllowed)
                                            }
                                        };
                                    else
                                    {
                                        var user = query.First();

                                        if (!user.Password.Equals(currentPassword))
                                            response.Errors = new ErrorResponse[]   {
                                                new ErrorResponse() {
                                                    For = "CurrentPassword",
                                                    Message = ApplicationErrorMessage.GetErrorMessage(ApplicationErrorMessages.InvalidPassword)
                                                }
                                            };
                                        else
                                        {
                                            try
                                            {
                                                if (currentUser.User.UserID == passwordDetail.UserID) currentUser.User.Password = newPassword;

                                                user.Password = newPassword;

                                                db.LogActivities.Add(new LogActivity()
                                                {
                                                    UserID = currentUser.User.UserID,
                                                    Action = ApplicationActions.Edit,
                                                    Remarks = string.Format("Updated user password (User ID: {0}).", user.UserID)
                                                });

                                                db.SaveChanges(); trans.Complete();
                                                response.Successful = true;
                                            }
                                            catch (Exception ex)
                                            {
                                                EventLog.WriteEntry(GetType().FullName, string.Format("Message: {0}\nStack Trace: {1}", ex.Message, ex.StackTrace), EventLogEntryType.Error);

                                                response.Errors = new ErrorResponse[] {
                                                    new ErrorResponse() {
                                                        Message = ex.Message,
                                                        StackTrace = ex.StackTrace
                                                    }
                                                };
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return Json(response);
        }

        public JsonResult Current()
        {
            if (Session[ApplicationSessionKeys.CurrentUser] != null)
            {
                var currentAccount = (ApplicationUser)Session[ApplicationSessionKeys.CurrentUser];

                return Json(currentAccount, JsonRequestBehavior.AllowGet);
            }

            return Json(new { Message = ApplicationErrorMessage.GetErrorMessage(ApplicationErrorMessages.ActionNotAllowed) }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult Update(AccountDetail account)
        {
            var response = new AccountUpdateResponse()
            {
                Account = account
            };

            if (Session[ApplicationSessionKeys.CurrentUser] == null)
                response.Errors = new ErrorResponse[] {
                        new ErrorResponse() {
                            Message = ApplicationErrorMessage.GetErrorMessage(ApplicationErrorMessages.ActionNotAllowed)
                        }
                    };
            else
            {
                if (!ModelState.IsValid) response.Errors = response.GetErrors(ModelState);
                else
                {
                    var currentUser = (ApplicationUser)Session[ApplicationSessionKeys.CurrentUser];
                    bool allowed = true;

                    if (!currentUser.User.IsAdmin) allowed = (currentUser.User.UserID == account.UserID);

                    if (!allowed)
                        response.Errors = new ErrorResponse[] {
                            new ErrorResponse() {
                                Message = ApplicationErrorMessage.GetErrorMessage(ApplicationErrorMessages.ActionNotAllowed)
                            }
                        };
                    else
                    {
                        using (TransactionScope trans = new TransactionScope())
                        {
                            using (DukeNUSDatabase db = new DukeNUSDatabase())
                            {
                                try
                                {
                                    var query = from users in db.Users
                                                where users.UserID == account.UserID
                                                select users;

                                    if (query.Any())
                                    {
                                        var user = query.First();
                                        user.UserName = account.UserName;
                                        user.FullName = account.FullName;
                                        user.Department = account.Department;
                                        user.Designation = account.Designation;
                                        user.Email = account.Email;
                                        user.DateModified = DateTime.Now;

                                        if (currentUser.User.UserID == account.UserID)
                                        {
                                            currentUser.User.UserName = account.UserName;
                                            currentUser.User.FullName = account.FullName;
                                            currentUser.User.Department = account.Department;
                                            currentUser.User.Designation = account.Designation;
                                            currentUser.User.Email = account.Email;
                                        }

                                        db.LogActivities.Add(new LogActivity()
                                        {
                                            UserID = currentUser.User.UserID,
                                            Action = ApplicationActions.Edit,
                                            Remarks = string.Format("Updated user profile for {0}[User ID: {1}].", user.FullName, user.UserID)
                                        });

                                        db.SaveChanges(); trans.Complete();
                                        response.Successful = true;
                                    }
                                }
                                catch (Exception ex)
                                {
                                    EventLog.WriteEntry(GetType().FullName, string.Format("Message: {0}\nStack Trace: {1}", ex.Message, ex.StackTrace), EventLogEntryType.Error);

                                    response.Errors = new ErrorResponse[] {
                                        new ErrorResponse() {
                                            Message = ex.Message,
                                            StackTrace = ex.StackTrace
                                        }
                                    };
                                }
                            }
                        }
                    }
                }
            }

            return Json(response);
        }

    }
}
